package com.cdp.zwy.zwy_manager_back_v1.config;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * JWT工具类 (已升级至最新JJWT API)
 */
@Component // 使用 @Component 注解
public class JwtUtils {

    // 必须是一个Base64编码的、足够长的密钥，用于HMAC-SHA算法。
    // 你可以用在线工具生成一个，或者就用下面这个。
    private static final String SECRET_KEY_BASE64 = "dGhpcy1pcy1hLXN1cGVyLWxvbmctYW5kLXNlY3VyZS1zZWNyZXQta2V5LWZvci1qd3QtaHMyNTYtYWxnb3JpdGhtLTEyMzQ1Cg";
      private final SecretKey key;

    public JwtUtils() {
        byte[] keyBytes = Decoders.BASE64.decode(SECRET_KEY_BASE64);
        this.key = Keys.hmacShaKeyFor(keyBytes);
    }

    public String extractUsername(String token) {
        return extractClaim(token, Claims::getSubject);
    }

    public Date extractExpiration(String token) {
        return extractClaim(token, Claims::getExpiration);
    }

    public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = extractAllClaims(token);
        return claimsResolver.apply(claims);
    }

    private Claims extractAllClaims(String token) {
        // 使用新的API进行解析
        return Jwts.parser()
                .verifyWith(this.key)
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    private Boolean isTokenExpired(String token) {
        return extractExpiration(token).before(new Date());
    }

    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        List<String> roles = userDetails.getAuthorities().stream()
                .map(GrantedAuthority::getAuthority)
                .collect(Collectors.toList());
        claims.put("roles", roles);
        return createToken(claims, userDetails.getUsername());
    }

    //  优化后的代码
    private String createToken(Map<String, Object> claims, String subject) {
        return Jwts.builder()
                .claims(claims) // 建议使用 claims() 替代 setClaims()，语义更流畅
                .subject(subject) // 建议使用 subject() 替代 setSubject()
                .issuedAt(new Date(System.currentTimeMillis()))
                .expiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10))
                .signWith(key) // 直接传入 SecretKey 对象，算法会根据密钥类型自动推断
                .compact();
    }

    // 修改后的 validateToken 方法
    public Boolean validateToken(String token, UserDetails userDetails) {
        try {
            final String username = extractUsername(token);
            return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
        } catch (Exception e) {
            // 加上这一行，把错误信息打印到控制台
            System.err.println("JWT Token validation error: " + e.getMessage());
            e.printStackTrace(); // 打印完整的堆栈信息，这非常关键！
            return false;
        }
    }
    public List<String> extractRoles(String token) {
        final Claims claims = extractAllClaims(token);
        return claims.get("roles", List.class);
    }
}